package com.relytosoft.mizar.media.analyze.services.service.structure.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.relytosoft.dubhe.common.core.base.page.PageQuery;
import com.relytosoft.dubhe.common.core.exception.ServiceException;
import com.relytosoft.dubhe.common.core.object.ResponseResult;
import com.relytosoft.dubhe.common.core.utils.BeanCopyUtils;
import com.relytosoft.dubhe.common.satoken.entity.CurrentUser;
import com.relytosoft.mizar.media.analyze.api.entity.structure.AyStructureTask;
import com.relytosoft.mizar.media.analyze.api.entity.structure.AyStructureTaskSon;
import com.relytosoft.mizar.media.analyze.api.pojo.dto.AyStructureTaskDto;
import com.relytosoft.mizar.media.analyze.api.pojo.query.AyStruDataQuery;
import com.relytosoft.mizar.media.analyze.api.pojo.query.AyStruMotorVehicleSearchQuery;
import com.relytosoft.mizar.media.analyze.api.pojo.query.AyStructurePersonSearchQuery;
import com.relytosoft.mizar.media.analyze.api.pojo.query.AyStructureTaskQuery;
import com.relytosoft.mizar.media.analyze.api.pojo.vo.*;
import com.relytosoft.mizar.media.analyze.services.mapper.structure.AyStructureTaskMapper;
import com.relytosoft.mizar.media.analyze.services.service.structure.AyStructureTaskService;
import com.relytosoft.mizar.media.analyze.services.service.structure.AyStructureTaskSonService;
import com.relytosoft.mizar.media.camera.api.feign.CameraFeignInService;
import com.relytosoft.mizar.media.camera.api.pojo.vo.CameraBasePlatform;
import com.relytosoft.mizar.media.common.config.properties.MizarAnalyzeProperties;
import com.relytosoft.mizar.media.common.entity.algo.AYPerson;
import com.relytosoft.mizar.media.common.entity.algo.AYVehicle;
import com.relytosoft.mizar.media.common.enums.DeleteStatusEnum;
import com.relytosoft.mizar.media.common.enums.TaskStatusEnum;
import com.relytosoft.mizar.media.external.api.analyze.request.StruDataReqDto;
import com.relytosoft.mizar.media.external.api.analyze.service.StructureService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * AyStructureTaskServiceImpl
 *
 * @Author SunLi
 * @Date: 2022/5/31 16:39
 * @Version 1.0
 */
@Service
public class AyStructureTaskServiceImpl extends ServiceImpl<AyStructureTaskMapper, AyStructureTask> implements AyStructureTaskService {

    @Resource
    private AyStructureTaskSonService ayStructureTaskSonService;

    @Resource
    private StructureService structureService;

    @Resource
    private CameraFeignInService cameraFeignInService;


    @Resource
    private MizarAnalyzeProperties analyzeProperties;

    @Override
    public IPage<AyStructureTaskVo> selectAyStructureTaskPageList(PageQuery pageQuery, AyStructureTaskQuery ayStructureTaskQuery) {
        if (StrUtil.isBlank(pageQuery.getOrderByColumn())) {
            pageQuery.setOrderByColumn("id");
            pageQuery.setIsAsc("desc");
        }
        if(Objects.isNull(ayStructureTaskQuery.getType())){
            ayStructureTaskQuery.setType(1);
        }
        if(StrUtil.isNotEmpty(ayStructureTaskQuery.getEndTime())){
            LocalDateTime endTime=  Convert.toLocalDateTime(ayStructureTaskQuery.getEndTime()).plusDays(1);
            ayStructureTaskQuery.setEndTime(endTime.format(DateTimeFormatter.ISO_LOCAL_DATE));
        }
        return baseMapper.selectPageTaskList(pageQuery.build(), ayStructureTaskQuery);
    }
    @Override
    public List<AyStructureTaskSon> buildTaskSon(AyStructureTaskDto ayStructureTaskDto)
    {
        //构造子任务列表
        List<AyStructureTaskSon> ayStructureTaskSonList=new ArrayList<>();
        for (AyCameraVo cameraVo : ayStructureTaskDto.getAyCameraVos()) {
            AyStructureTaskSon ayStructureTaskSon = new AyStructureTaskSon();
            BeanCopyUtils.copy(cameraVo,ayStructureTaskSon);
            ayStructureTaskSon.setTaskName(ayStructureTaskDto.getName());
            ayStructureTaskSon.setStatus(ayStructureTaskDto.getStatus());
            ayStructureTaskSon.setType(ayStructureTaskDto.getType());
            if(ayStructureTaskDto.getStatus()==TaskStatusEnum.CREATED.getValue()){
                ayStructureTaskSon.setBeginTime(LocalDateTime.now());
            }
            ayStructureTaskSonList.add(ayStructureTaskSon);
        }
        return ayStructureTaskSonList;
    }
    @Override
    public void taskStatusHandle(Integer id, Integer newStatus) {
        String updateBy=CurrentUser.getCurrentUserFullName();
        if(StrUtil.isEmpty(updateBy)){
            updateBy="SYSTEM";
        }
        if(newStatus==TaskStatusEnum.CREATED.getValue()){
            //启动成功联动处理主任务状态
            List<Integer> status=new ArrayList<>(Arrays.asList(TaskStatusEnum.FINISHED.getValue(),TaskStatusEnum.NOT_STARTED.getValue(),TaskStatusEnum.RUNING.getValue()));

            baseMapper.update(null,new LambdaUpdateWrapper<AyStructureTask>().set(AyStructureTask::getStatus,newStatus).set(AyStructureTask::getUpdatedId, CurrentUser.getCurrentUserId()).set(AyStructureTask::getUpdatedBy, updateBy).set(AyStructureTask::getEndTime,null).set(AyStructureTask::getBeginTime,LocalDateTime.now())
                    .eq(AyStructureTask::getId,id).eq(AyStructureTask::getIsDeleted,DeleteStatusEnum.NOT_DELETED.getValue()).in(AyStructureTask::getStatus,status));
        }
        else if(newStatus==TaskStatusEnum.FINISHED.getValue()){
            updateStatusFinished(id,updateBy);
        }else if(newStatus==TaskStatusEnum.RUNING.getValue()){
            updateStatusRuning(id,updateBy);
        }
    }
    @Override
    public void updateStatusByDeleteUnusual(Integer id){
        //查询所有未删除的子任务
        LambdaQueryWrapper<AyStructureTaskSon> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(AyStructureTaskSon::getStructureTaskId,id);
        wrapper.eq(AyStructureTaskSon::getIsDeleted,DeleteStatusEnum.NOT_DELETED.getValue());
        List<Integer> status=new ArrayList<>(Arrays.asList(TaskStatusEnum.CREATED.getValue(),TaskStatusEnum.RUNING.getValue(),TaskStatusEnum.UNUSUAL.getValue()));
        wrapper.in(AyStructureTaskSon::getStatus,status);
        List<AyStructureTaskSon> taskSonList=ayStructureTaskSonService.list(wrapper);
        if(!taskSonList.isEmpty()){
            //是否还有异常任务
            boolean hasUnusual=taskSonList.stream().anyMatch(s -> s.getStatus()==TaskStatusEnum.UNUSUAL.getValue());
            //是否有运行中的任务
            boolean hasRunning=taskSonList.stream().anyMatch(s -> s.getStatus()==TaskStatusEnum.RUNING.getValue());
            //是否有创建中的任务
            boolean hasCreate=taskSonList.stream().anyMatch(s -> s.getStatus()==TaskStatusEnum.CREATED.getValue());
            if(!hasUnusual){
                //没有异常任务
                if(hasCreate){
                    //有创建中的任务
                    AyStructureTask updateTask=new AyStructureTask();
                    updateTask.setId(id);
                    updateTask.setStatus(TaskStatusEnum.CREATED.getValue());
                    updateTask.setUpdatedBy(CurrentUser.getCurrentUserFullName());
                    this.updateById(updateTask);
                }else if(hasRunning){
                    //有运行中的任务
                    AyStructureTask updateTask=new AyStructureTask();
                    updateTask.setId(id);
                    updateTask.setStatus(TaskStatusEnum.RUNING.getValue());
                    updateTask.setUpdatedBy(CurrentUser.getCurrentUserFullName());
                    this.updateById(updateTask);
                }
            }
        }
    }

    private void updateStatusFinished(Integer id,String updateBy){
        //查询是否还有状态为创建中及运行中、异常且未删除的子任务
        LambdaQueryWrapper<AyStructureTaskSon> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(AyStructureTaskSon::getStructureTaskId,id);
        wrapper.eq(AyStructureTaskSon::getIsDeleted,DeleteStatusEnum.NOT_DELETED.getValue());
        List<Integer> status=new ArrayList<>(Arrays.asList(TaskStatusEnum.CREATED.getValue(),TaskStatusEnum.RUNING.getValue(),TaskStatusEnum.UNUSUAL.getValue()));
        wrapper.in(AyStructureTaskSon::getStatus,status);
        List<AyStructureTaskSon> taskSonList=ayStructureTaskSonService.list(wrapper);
        if(taskSonList.isEmpty()){
            //没有状态为创建中及运行中、异常的子任务，需更新任务为已结束
            AyStructureTask updateTask=new AyStructureTask();
            updateTask.setId(id);
            updateTask.setStatus(TaskStatusEnum.FINISHED.getValue());
            updateTask.setEndTime(LocalDateTime.now());
            updateTask.setUpdatedBy(updateBy);
            this.updateById(updateTask);
        }
        else {
            //是否还有异常任务
            boolean hasUnusual=taskSonList.stream().anyMatch(s -> s.getStatus()==TaskStatusEnum.UNUSUAL.getValue());
            //是否有运行中的任务
            boolean hasRunning=taskSonList.stream().anyMatch(s -> s.getStatus()==TaskStatusEnum.RUNING.getValue());
            if(!hasUnusual&&hasRunning){
                //无异常有运行中
                AyStructureTask updateTask=new AyStructureTask();
                updateTask.setId(id);
                updateTask.setStatus(TaskStatusEnum.RUNING.getValue());
                updateTask.setUpdatedBy(updateBy);
                this.updateById(updateTask);
            }
        }
    }
    private void updateStatusRuning(Integer id,String updateBy){
        //查询是否还有状态为创建中或异常且未删除的子任务
        LambdaQueryWrapper<AyStructureTaskSon> wrapper1 = Wrappers.lambdaQuery();
        wrapper1.eq(AyStructureTaskSon::getStructureTaskId,id);
        wrapper1.eq(AyStructureTaskSon::getIsDeleted,DeleteStatusEnum.NOT_DELETED.getValue());
        List<Integer> status=new ArrayList<>(Arrays.asList(TaskStatusEnum.CREATED.getValue(),TaskStatusEnum.UNUSUAL.getValue()));
        wrapper1.in(AyStructureTaskSon::getStatus,status);
        if(ayStructureTaskSonService.count(wrapper1)==0) {
            //创建中的状态变为运行中
            LambdaQueryWrapper<AyStructureTask> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(AyStructureTask::getId, id);
            wrapper.eq(AyStructureTask::getIsDeleted, DeleteStatusEnum.NOT_DELETED.getValue());
            wrapper.eq(AyStructureTask::getStatus, TaskStatusEnum.CREATED.getValue());

            AyStructureTask updateTask = new AyStructureTask();
            updateTask.setStatus(TaskStatusEnum.RUNING.getValue());
            updateTask.setUpdatedBy(updateBy);

            this.update(updateTask, wrapper);
        }
    }
    @Override
    public List<AyStructureTask> buildDeleteTask(List<Integer> ids){
        //主任务删除验证
        if (!deleteTaskFrontVerify(ids)) {
            return null;
        }
        //子任务删除验证
        if (!deleteSonTaskFrontVerify(ids)) {
            return null;
        }
        List<AyStructureTask> deleteTaskList=new ArrayList<>();
        for (Integer id : ids) {
            AyStructureTask task=new AyStructureTask();
            task.setId(id);
            task.setIsDeleted(DeleteStatusEnum.DELETED.getValue());
            task.setUpdatedId(CurrentUser.getCurrentUserId());
            task.setUpdatedBy(CurrentUser.getCurrentUserFullName());
            deleteTaskList.add(task);
        }
        return deleteTaskList;
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteTaskTrans(List<Integer> ids,List<AyStructureTask> deleteTaskList){
        boolean deleteRes= this.updateBatchById(deleteTaskList,deleteTaskList.size());
        if(deleteRes){
            deleteRes=ayStructureTaskSonService.deleteByTask(ids);
            if(!deleteRes){
                throw new ServiceException("任务删除失败！");
            }
        }
    }

    @Override
    public List<AyStructureTaskSon> selectCanStartTaskSonList(List<Integer> ids) {
        //通过子任务筛选可启动的任务
        LambdaQueryWrapper<AyStructureTaskSon> wrapper = Wrappers.lambdaQuery();
        wrapper.in(AyStructureTaskSon::getStructureTaskId, ids);
        wrapper.eq(AyStructureTaskSon::getIsDeleted,DeleteStatusEnum.NOT_DELETED.getValue());
        List<Integer> status=new ArrayList<>(Arrays.asList(TaskStatusEnum.FINISHED.getValue(),TaskStatusEnum.NOT_STARTED.getValue()));
        wrapper.in(AyStructureTaskSon::getStatus,status);

        return ayStructureTaskSonService.list(wrapper);
    }

    @Override
    public List<AyStructureTaskSon> selectCanStopTaskSonList(List<Integer> ids) {
        //通过子任务筛选可停止的任务
        LambdaQueryWrapper<AyStructureTaskSon> wrapper = Wrappers.lambdaQuery();
        wrapper.in(AyStructureTaskSon::getStructureTaskId, ids);
        wrapper.eq(AyStructureTaskSon::getIsDeleted,DeleteStatusEnum.NOT_DELETED.getValue());
        //未删除的运行中、异常或创建中更新时间已过指定配置的任务
        List<Integer> status=new ArrayList<>(Arrays.asList(TaskStatusEnum.RUNING.getValue(),TaskStatusEnum.UNUSUAL.getValue()));
        wrapper.and(w -> w.in(AyStructureTaskSon::getStatus,status).or(w1->w1.eq(AyStructureTaskSon::getStatus,TaskStatusEnum.CREATED.getValue()).lt(AyStructureTaskSon::getUpdatedTime,LocalDateTime.now().plusSeconds(-1*analyzeProperties.getTaskCanStopTime()))));
        return ayStructureTaskSonService.list(wrapper);
    }

    @Override
    public void updateSonTaskName(Integer id, String taskName) {
        LambdaQueryWrapper<AyStructureTaskSon> wrapper=Wrappers.lambdaQuery();
        wrapper.eq(AyStructureTaskSon::getStructureTaskId,id);
        wrapper.eq(AyStructureTaskSon::getIsDeleted,DeleteStatusEnum.NOT_DELETED.getValue());
        AyStructureTaskSon ayStructureTaskSon = new AyStructureTaskSon();
        ayStructureTaskSon.setTaskName(taskName);
        ayStructureTaskSonService.update(ayStructureTaskSon, wrapper);
    }

    @Override
    public JSONObject searchAll(AyStruDataQuery struDataQuery) {

        StruDataReqDto reqDto= this.buildStruDataReqDto(struDataQuery);

        return searchStruData(reqDto);
    }

    @Override
    public JSONObject searchPerson(AyStruDataQuery struDataQuery, AyStructurePersonSearchQuery personSearchQuery) {

        StruDataReqDto reqDto= this.buildStruDataReqDto(struDataQuery);

        reqDto.setPerson(BeanCopyUtils.copy(personSearchQuery,AYPerson.class));

        return searchStruData(reqDto);
    }

    @Override
    public JSONObject searchVehicle(AyStruDataQuery struDataQuery, AyStruMotorVehicleSearchQuery vehicleSearchQuery) {

        StruDataReqDto reqDto= this.buildStruDataReqDto(struDataQuery);

        reqDto.setMotorVehicle(BeanCopyUtils.copy(vehicleSearchQuery,AYVehicle.class));

        return searchStruData(reqDto);
    }

    @Override
    public List<AyTaskSelectVo> selectTaskList() {
        return baseMapper.selectTaskList();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean insertTaskWithSonWith(AyStructureTask ayStructureTask,List<AyStructureTaskSon> ayStructureTaskSonList) {
        boolean save = this.save(ayStructureTask);
        if (save) {
            for (AyStructureTaskSon taskSon:ayStructureTaskSonList){
                taskSon.setStructureTaskId(ayStructureTask.getId());
            }
            boolean saveSon=ayStructureTaskSonService.saveBatch(ayStructureTaskSonList,ayStructureTaskSonList.size());
            if(!saveSon){
                throw new ServiceException("创建结构化任务失败");
            }
            return saveSon;
        }
        throw new ServiceException("创建结构化任务失败");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean startTaskWithSon(AyStructureTask ayStructureTask,List<AyStructureTaskSon> deleteTaskSons,List<AyStructureTaskSon> insertTaskSons,List<AyStructureTaskSon> startTaskSons){

        List<Integer> status=new ArrayList<>(Arrays.asList(TaskStatusEnum.FINISHED.getValue(),TaskStatusEnum.NOT_STARTED.getValue(),TaskStatusEnum.UNUSUAL.getValue()));

        boolean result= baseMapper.update(null,new LambdaUpdateWrapper<AyStructureTask>().set(AyStructureTask::getStatus,ayStructureTask.getStatus()).set(AyStructureTask::getUpdatedId, CurrentUser.getCurrentUserId()).set(AyStructureTask::getUpdatedBy, CurrentUser.getCurrentUserFullName()).set(AyStructureTask::getUpdatedTime, LocalDateTime.now()).set(AyStructureTask::getEndTime,null).set(AyStructureTask::getBeginTime,LocalDateTime.now())
                .eq(AyStructureTask::getId,ayStructureTask.getId()).eq(AyStructureTask::getIsDeleted,DeleteStatusEnum.NOT_DELETED.getValue()).in(AyStructureTask::getStatus,status))==1;


        if(result){
            boolean deleteAndStartRes;
            if (!deleteTaskSons.isEmpty()) {
                deleteAndStartRes=ayStructureTaskSonService.deleteAndStartTaskSonList(deleteTaskSons, insertTaskSons,ayStructureTask.getId());
            }
            else{
                deleteAndStartRes=true;
            }
            boolean startRes;
            if(!startTaskSons.isEmpty()){
                startRes= ayStructureTaskSonService.startTaskSonList(startTaskSons,ayStructureTask.getId());
            }
            else{
                startRes=true;
            }
            if(!deleteAndStartRes||!startRes){
                throw new ServiceException("启动任务失败");
            }
        }
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean stopTaskWithSon(AyStructureTask ayStructureTask,List<AyStructureTaskSon> stopTaskSons){
        boolean result=this.updateById(ayStructureTask);
        if(result) {
            boolean stopRes=ayStructureTaskSonService.stopTaskSonList(stopTaskSons,ayStructureTask.getId());
            if(!stopRes){
                throw new ServiceException("停止任务失败");
            }
        }
        return result;
    }

    /**
     * 任务添加前置验证
     *
     * @param ayStructureTaskDto
     * @return false 表示验证未通过 true 验证通过
     */
    @Override
    public Boolean addFrontVerify(AyStructureTaskDto ayStructureTaskDto) {

        List<AyCameraVo> ayCameraVos = ayStructureTaskDto.getAyCameraVos();
        //查询设备是否有未删除的分析任务
        List<String> cameraIds=ayCameraVos.stream().map(AyCameraVo::getCameraId).collect(Collectors.toList());

        List<AyStructureTaskSon> taskSons = ayStructureTaskSonService.list(new LambdaQueryWrapper<AyStructureTaskSon>()
                .in(AyStructureTaskSon::getCameraId, cameraIds)
                .eq(AyStructureTaskSon::getIsDeleted, DeleteStatusEnum.NOT_DELETED.getValue()));
        if(taskSons.isEmpty()){
            return true;
        }
        Iterator<AyCameraVo> cameraVoIterator = ayCameraVos.iterator();
        while (cameraVoIterator.hasNext()) {
            AyCameraVo cameraVo = cameraVoIterator.next();
            //过滤已经存在的camera
            AyStructureTaskSon taskSon=taskSons.stream().filter(d->d.getCameraId().equals(cameraVo.getCameraId())).findAny().orElse(null);
            if (!Objects.isNull(taskSon)) {
                cameraVoIterator.remove();
            }
        }
        return !ayCameraVos.isEmpty();
    }
    /**
     * 任务删除前置验证
     *
     * @param ids 主任务集合
     * @return false验证不通过 true验证通过
     */
    private Boolean deleteTaskFrontVerify(List<Integer> ids) {
        if (ids.isEmpty()) {
            return false;
        }
        //未删除的已结束、未启动、异常任务
        LambdaQueryWrapper<AyStructureTask> wrapper = Wrappers.lambdaQuery();
        wrapper.in(AyStructureTask::getId, ids);
        wrapper.eq(AyStructureTask::getIsDeleted,DeleteStatusEnum.NOT_DELETED.getValue());
        List<Integer> status=new ArrayList<>(Arrays.asList(TaskStatusEnum.FINISHED.getValue(),TaskStatusEnum.NOT_STARTED.getValue(),TaskStatusEnum.UNUSUAL.getValue()));
        wrapper.in(AyStructureTask::getStatus,status);
        wrapper.select(AyStructureTask::getId);
        List<Object> canDeleteIds=this.listObjs(wrapper);
        if(canDeleteIds.isEmpty()){
            return false;
        }
        //重新为可删除的任务ID赋值
        ids=(List<Integer>)(List)canDeleteIds;
        return true;
    }

    /**
     * 子任务删除前置验证
     *
     * @param ids 主任务id
     * @return false 验证不通过 true 通过
     */
    private Boolean deleteSonTaskFrontVerify(List<Integer> ids) {
        LambdaQueryWrapper<AyStructureTaskSon> wrapper = Wrappers.lambdaQuery();
        wrapper.in(AyStructureTaskSon::getStructureTaskId,ids);
        wrapper.eq(AyStructureTaskSon::getIsDeleted,DeleteStatusEnum.NOT_DELETED.getValue());
        //有运行中、创建中的子任务时，不允许删除
        List<Integer> status=new ArrayList<>(Arrays.asList(TaskStatusEnum.CREATED.getValue(),TaskStatusEnum.RUNING.getValue()));
        wrapper.in(AyStructureTaskSon::getStatus,status);
        wrapper.select(AyStructureTaskSon::getStructureTaskId);
        //筛选出不能删除的主任务ID
        List<Object> canNotDeleteTaskSons=ayStructureTaskSonService.listObjs(wrapper);
        if(!canNotDeleteTaskSons.isEmpty()){
            List<Integer> newIds = (List<Integer>)(List)canNotDeleteTaskSons;
            Iterator<Integer> idsIterator=ids.iterator();
            while (idsIterator.hasNext()){
                Integer id=idsIterator.next();
                if(newIds.contains(id)){
                    //移出不能删除的主任务ID
                    idsIterator.remove();
                }
            }
        }
        return !ids.isEmpty();
    }

    /**
     * 任务启动前置验证
     *
     * @param ids
     * @return
     */
    @Override
    public boolean startTaskFrontVerify(List<Integer> ids) {
        if (ids.isEmpty()) {
            return false;
        }
        //筛选出未删除的已结束、未启动的任务
        LambdaQueryWrapper<AyStructureTask> wrapper = Wrappers.lambdaQuery();
        wrapper.in(AyStructureTask::getId, ids);
        wrapper.eq(AyStructureTask::getIsDeleted,DeleteStatusEnum.NOT_DELETED.getValue());
        List<Integer> status=new ArrayList<>(Arrays.asList(TaskStatusEnum.FINISHED.getValue(),TaskStatusEnum.NOT_STARTED.getValue()));
        wrapper.in(AyStructureTask::getStatus,status);
        wrapper.select(AyStructureTask::getId);
        List<Object> canStartTaskIds=this.listObjs(wrapper);
        if(canStartTaskIds.isEmpty()){
            return false;
        }
        //子任务启动验证
        return startSonTaskFrontVerify(ids);
    }

    /**
     * 子任务启动前置验证
     *
     * @param ids 主任务id
     * @return false 验证不通过 true 通过
     */
    private Boolean startSonTaskFrontVerify(List<Integer> ids) {
        if (ids.isEmpty()) {
            return false;
        }
        LambdaQueryWrapper<AyStructureTaskSon> wrapper = Wrappers.lambdaQuery();
        wrapper.in(AyStructureTaskSon::getStructureTaskId,ids);
        wrapper.eq(AyStructureTaskSon::getIsDeleted,DeleteStatusEnum.NOT_DELETED.getValue());
        //有运行中、创建中、异常的子任务时，不允许启动
        List<Integer> status=new ArrayList<>(Arrays.asList(TaskStatusEnum.CREATED.getValue(),TaskStatusEnum.RUNING.getValue(),TaskStatusEnum.UNUSUAL.getValue()));
        wrapper.in(AyStructureTaskSon::getStatus,status);
        wrapper.select(AyStructureTaskSon::getStructureTaskId);
        //筛选出不能启动的主任务ID
        List<Object> canNotStartTaskSons=ayStructureTaskSonService.listObjs(wrapper);
        if(!canNotStartTaskSons.isEmpty()){
            List<Integer> newIds = (List<Integer>)(List)canNotStartTaskSons;
            Iterator<Integer> idsIterator=ids.iterator();
            while (idsIterator.hasNext()){
                Integer id=idsIterator.next();
                if(newIds.contains(id)){
                    //移出不能删除的主任务ID
                    idsIterator.remove();
                }
            }
        }
        return !ids.isEmpty();
    }
    /**
     * 任务停止前置验证
     *
     * @param ids
     * @return false 验证不通过 true 通过
     */
    @Override
    public boolean stopTaskFrontVerify(List<Integer> ids) {
        if (ids.isEmpty()) {
            return false;
        }
        //未删除的运行中、异常、创建中更新时间已过指定配置的任务
        LambdaQueryWrapper<AyStructureTask> wrapper = Wrappers.lambdaQuery();
        wrapper.in(AyStructureTask::getId, ids);
        wrapper.eq(AyStructureTask::getIsDeleted,DeleteStatusEnum.NOT_DELETED.getValue());
        List<Integer> status=new ArrayList<>(Arrays.asList(TaskStatusEnum.RUNING.getValue(),TaskStatusEnum.UNUSUAL.getValue()));
        wrapper.and(w -> w.in(AyStructureTask::getStatus,status).or(w1->w1.eq(AyStructureTask::getStatus,TaskStatusEnum.CREATED.getValue()).lt(AyStructureTask::getUpdatedTime,LocalDateTime.now().plusSeconds(-1*analyzeProperties.getTaskCanStopTime()))));
        List<Object> canStopTaskIds=this.listObjs(wrapper);
        if(canStopTaskIds.isEmpty()){
            return false;
        }
        ids = (List<Integer>)(List)canStopTaskIds;
        return true;
    }



    private StruDataReqDto buildStruDataReqDto(AyStruDataQuery struDataQuery){
        StruDataReqDto reqDto= BeanCopyUtils.copy(struDataQuery,StruDataReqDto.class);
        //实时分析任务
        reqDto.setTaskType(1);
        //任务及设备同时有值表示查询指定主任务下的指定设备的所有子任务
        if(StrUtil.isNotEmpty(struDataQuery.getDeviceIds())&&struDataQuery.getTaskId()!=null){
            //获取子任务ID
            reqDto.setTaskIds(ayStructureTaskSonService.getTaskIds(struDataQuery.getTaskId(),struDataQuery.getDeviceIds()));
        }
        else{
            //按设备查
            if (!StrUtil.isEmptyIfStr(struDataQuery.getDeviceIds())) {
                reqDto.setDeviceIds(
                        Arrays.asList(struDataQuery.getDeviceIds().split(",")));
            }
            //按任务查
            if (struDataQuery.getTaskId()!=null) {
                //获取子任务ID
                reqDto.setTaskIds(ayStructureTaskSonService.getTaskIds(struDataQuery.getTaskId()));
            }

        }
        return reqDto;
    }

    public List<EsStructureVo> struApplicationSearch(JSONObject jsonObject) {
        JSONArray items = jsonObject.getJSONArray("items");
        if (items == null) {
            return new ArrayList<>();
        }
        List<EsStructureVo> esStructureVos = JSON.parseArray(items.toJSONString(), EsStructureVo.class);
        ResponseResult<List<CameraBasePlatform>> result = cameraFeignInService.findCameraCode("BTDL", 1);
        List<CameraBasePlatform> resultData = result.getData();
        //resultData转为map，键位platformCameraCode，值为name
        Map<String, String> cameraMap = resultData
                .stream()
                .collect(Collectors.toMap(CameraBasePlatform::getPlatformCameraCode, CameraBasePlatform::getName));
        for (EsStructureVo item : esStructureVos) {
            if (item.getDataType() == 1) {
                EsStruPersonVo person = item.getPerson();
                person.setDeviceName(cameraMap.get(person.getDeviceId()));
                person.setImage(getPicUrl(person.getImage()));
                person.setThumb(getPicUrl(person.getThumb()));
            } else if (item.getDataType() == 2) {
                EsStruVehicleVo vehicle = item.getMotorVehicle();
                vehicle.setDeviceName(cameraMap.get(vehicle.getDeviceId()));
                vehicle.setImage(getPicUrl(vehicle.getImage()));
                vehicle.setThumb(getPicUrl(vehicle.getThumb()));
            }else if(item.getDataType()==3){
                EsStruNonVehicleVo nonVehicle=item.getNonMotorVehicle();
                nonVehicle.setDeviceName(cameraMap.get(nonVehicle.getDeviceId()));
                nonVehicle.setImage(getPicUrl(nonVehicle.getImage()));
                nonVehicle.setThumb(getPicUrl(nonVehicle.getThumb()));
            }
        }
        return esStructureVos;
    }

    public String getPicUrl(String url) {
        int http = url.lastIndexOf("http");
        return url.substring(http);
    }
    private JSONObject searchStruData(StruDataReqDto reqDto){
        ResponseResult result = structureService.searchStructureData(reqDto);
        if(result.getCode()==ResponseResult.SUCCESS){
            JSONObject jsonObject = JSONObject.parseObject(result.getData().toString());
            List<EsStructureVo> esFaceVos = struApplicationSearch(jsonObject);
            jsonObject.put("items", esFaceVos);
            return jsonObject;
        }
        throw new ServiceException(result.getMsg());
    }
}
